<template>
  <div class="simple-code-editor">
    <div class="editor-toolbar">
      <div class="toolbar-left">
        <el-button size="small" @click="formatJSON" type="primary" :loading="formatting">
          <el-icon>
            <Document />
          </el-icon>
          格式化
        </el-button>
        <el-button size="small" @click="validateJSON" type="success">
          <el-icon>
            <Check />
          </el-icon>
          验证
        </el-button>
        <el-button size="small" @click="minifyJSON" type="warning" :loading="minifying">
          <el-icon>
            <Delete />
          </el-icon>
          压缩
        </el-button>
      </div>
      <div class="toolbar-right">
        <span style="color: #d4d4d4; font-size: 12px;">简单编辑器</span>
      </div>
    </div>
    <div class="editor-container">
      <div class="line-numbers" ref="lineNumbersRef">
        <div v-for="(line, index) in lineNumbers" :key="index" class="line-number">
          {{ line }}
        </div>
      </div>
      <textarea ref="textareaRef" v-model="content" :placeholder="placeholder" :readonly="readOnly"
        :class="['code-textarea', { 'error': hasError }]" @input="handleInput" @scroll="handleScroll"
        @blur="handleBlur"></textarea>

    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { Document, Check, Delete } from '@element-plus/icons-vue'

const props = defineProps({
  modelValue: {
    type: [String, Object],
    default: ''
  },
  language: {
    type: String,
    default: 'json'
  },

  readOnly: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: '请输入JSON内容...'
  }
})

const emit = defineEmits(['update:modelValue', 'change'])

const textareaRef = ref(null)
const lineNumbersRef = ref(null)
const content = ref('')
const formatting = ref(false)
const minifying = ref(false)
const hasError = ref(false)

// 计算行号
const lineNumbers = computed(() => {
  const lines = content.value.split('\n')
  return Array.from({ length: lines.length }, (_, i) => i + 1)
})

// 处理输入
const handleInput = () => {
  // 输入时清除错误状态
  hasError.value = false
  emit('update:modelValue', content.value)
  emit('change', content.value)
}

// 处理失焦事件 - 自动校验JSON
const handleBlur = () => {
  if (props.language === 'json' && content.value.trim()) {
    try {
      JSON.parse(content.value)
      hasError.value = false
    } catch (error) {
      hasError.value = true
    }
  }
}

// 同步滚动
const handleScroll = () => {
  if (lineNumbersRef.value && textareaRef.value) {
    lineNumbersRef.value.scrollTop = textareaRef.value.scrollTop
  }
}

// 格式化JSON
const formatJSON = async () => {
  if (formatting.value) return

  formatting.value = true
  try {
    if (!content.value.trim()) {
      ElMessage.warning('编辑器内容为空')
      return
    }

    const parsed = JSON.parse(content.value)
    const formatted = JSON.stringify(parsed, null, 2)
    content.value = formatted
    handleInput()
    ElMessage.success('JSON格式化成功')
  } catch (error) {
    ElMessage.error(`JSON格式错误: ${error.message}`)
  } finally {
    formatting.value = false
  }
}

// 验证JSON
const validateJSON = () => {
  try {
    if (!content.value.trim()) {
      ElMessage.warning('编辑器内容为空')
      return
    }

    JSON.parse(content.value)
    ElMessage.success('JSON格式验证通过 ✓')
  } catch (error) {
    ElMessage.error(`JSON格式错误: ${error.message}`)
  }
}

// 压缩JSON
const minifyJSON = async () => {
  if (minifying.value) return

  minifying.value = true
  try {
    if (!content.value.trim()) {
      ElMessage.warning('编辑器内容为空')
      return
    }

    const parsed = JSON.parse(content.value)
    const minified = JSON.stringify(parsed)
    content.value = minified
    handleInput()
    ElMessage.success('JSON压缩成功')
  } catch (error) {
    ElMessage.error(`JSON格式错误: ${error.message}`)
  } finally {
    minifying.value = false
  }
}

// 监听modelValue变化
watch(() => props.modelValue, (newValue) => {
  const newValueStr = typeof newValue === 'string' ? newValue : JSON.stringify(newValue, null, 2)
  if (content.value !== newValueStr) {
    content.value = newValueStr
  }
}, { immediate: true })

// 获取编辑器值
const getValue = () => content.value

// 设置编辑器值
const setValue = (value) => {
  content.value = value
  handleInput()
}

// 暴露方法给父组件
defineExpose({
  getValue,
  setValue,
  formatJSON,
  validateJSON,
  minifyJSON
})

onMounted(() => {

})
</script>

<style scoped>
.simple-code-editor {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  overflow: hidden;
  background: #1e1e1e;
  transition: border-color 0.3s ease;
}

.simple-code-editor:has(.code-textarea.error) {
  border-color: #f56c6c;
}

.editor-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: #2d2d2d;
  border-bottom: 1px solid #404040;
  gap: 12px;
}

.toolbar-left {
  display: flex;
  gap: 8px;
}

.toolbar-right {
  display: flex;
  align-items: center;
}

.editor-container {
  flex: 1;
  overflow-y: scroll;
  position: relative;
  display: flex;
  background: #1e1e1e;
}

.line-numbers {
  width: 50px;
  background: #252526;
  border-right: 1px solid #404040;
  padding: 16px 8px 16px 4px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  line-height: 19.5px;
  /* 精确匹配textarea */
  color: #858585;
  user-select: none;
  overflow: hidden;
  text-align: right;
  box-sizing: border-box;
}

.line-number {
  height: 19.5px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 4px;
}

.code-textarea {
  flex: 1;
  height: 100%;
  padding: 16px;
  border: none;
  background: #1e1e1e;
  color: #d4d4d4;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  line-height: 19.5px;
  /* 精确行高 */
  resize: none;
  outline: none;
  tab-size: 2;
  overflow-y: auto;
  overflow-x: auto;
  white-space: pre;
  word-wrap: break-word;
  box-sizing: border-box;
  /* 确保文本可以被选中和输入 */
  user-select: text !important;
  -webkit-user-select: text !important;
  -moz-user-select: text !important;
  -ms-user-select: text !important;
  
}

.code-textarea::selection {
  background: #264f78;
  color: #ffffff;
}

.code-textarea::-moz-selection {
  background: #264f78;
  color: #ffffff;
}

.code-textarea::placeholder {
  color: #858585;
}

.code-textarea.error {
  border-left: 3px solid #f56c6c;
  background: #1e1e1e;
}

/* 按钮样式 */
.editor-toolbar .el-button {
  background: #3c3c3c;
  border-color: #404040;
  color: #ffffff;
  font-size: 12px;
  padding: 6px 12px;
  height: 32px;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.editor-toolbar .el-button:hover {
  background: #4a4a4a;
  border-color: #505050;
}

.editor-toolbar .el-button--primary {
  background: #409eff;
  border-color: #409eff;
}

.editor-toolbar .el-button--success {
  background: #67c23a;
  border-color: #67c23a;
}

.editor-toolbar .el-button--warning {
  background: #e6a23c;
  border-color: #e6a23c;
}
</style>
